import request from "./request.js";
import io from "@hyoga/uni-socket.io";
// 用户状态服务 - 使用hyoga/uni-socket.io版本
class UserStatusService {
  constructor() {
    this.socket = null; // 使用hyoga/uni-socket.io的socket实例
    this.statusCallbacks = new Map();
    this.messageCallbacks = new Map();
    this.isConnected = false;
    this.reconnectCount = 0;
    this.reconnectTimeout = null;
    this.token = null;
    this.heartbeatInterval = null;
  }

  // 初始化Socket.IO连接（使用hyoga/uni-socket.io）
  initWebSocket() {
    try {
      // 优先使用accessToken
      this.token = uni.getStorageSync("accessToken") || uni.getStorageSync("token");

      if (!this.token) {
        console.warn("未找到Token，无法建立WebSocket连接");
        // 在开发环境下，可以使用一个模拟token
        if (process.env.NODE_ENV === "development") {
          this.token = "mock-token-for-development";
          console.log("使用模拟token进行开发测试");
        } else {
          return;
        }
      }

      // 避免重复连接
      if (this.socket && this.isConnected) {
        console.log("Socket.IO已经连接，无需重复初始化");
        return;
      }

      // 记录重连次数，避免无限重连
      if (this.reconnectCount > 5) {
        console.warn("Socket.IO重连次数过多(已达5次)，暂停重连");
        // 5分钟后可以尝试重新连接
        setTimeout(() => {
          this.reconnectCount = 0;
          console.log("重连限制已重置，可以尝试重新连接");
        }, 5 * 60 * 1000);
        return;
      }

      // 清除之前可能存在的socket
      if (this.socket) {
        try {
          this.socket.disconnect();
        } catch (e) {
          console.warn("关闭旧连接失败:", e);
        }
        this.socket = null;
      }

      console.log(
        `尝试建立Socket.IO连接${
          this.reconnectCount > 0 ? `(第${this.reconnectCount}次重连)` : ""
        }，token: ${this.token.substring(0, 10)}...`
      );

      // 创建Socket.IO连接（使用hyoga/uni-socket.io）
      const getWebSocketURL = () => {
        // 对于小程序环境，即使在开发模式下也使用实际IP地址
        // 因为小程序无法访问localhost
        return process.env.NODE_ENV === "development" &&
          typeof window !== "undefined"
          ? "ws://localhost:3000" // 浏览器环境可以使用localhost
          : "ws://192.168.0.154:3000"; // 小程序环境使用实际IP
      };

      this.socket = io(getWebSocketURL(), {
        query: { token: this.token },
        transports: ["websocket"],
        timeout: 60000,
        reconnection: false, // 禁用自动重连，使用我们自己的重连逻辑
        // hyoga/uni-socket.io特有的配置
        reconnectionAttempts: 5,
        reconnectionDelay: 1000,
        reconnectionDelayMax: 30000,
        forceNew: true,
        upgrade: false,
        rejectUnauthorized: false,
        timestampRequests: true,
        timestampParam: "t",
      });

      // 连接错误事件
      console.log("当前运行平台:", uni.getSystemInfoSync().platform);
      console.log("WebSocket URL:", getWebSocketURL());

      // 修改连接错误处理，增加更详细的日志
      this.socket.on("error", (err) => {
        console.error("Socket.IO连接错误:", err);
        console.error("错误详情:", JSON.stringify(err));
        this.isConnected = false;
        this.reconnectCount++;
        if (this.reconnectCount <= 5) {
          this.scheduleReconnect();
        }
      });

      // 连接断开事件
      this.socket.on("disconnect", (reason) => {
        console.log(`Socket.IO连接已断开，原因: ${reason}`);
        this.isConnected = false;

        // 停止心跳
        if (this.heartbeatInterval) {
          clearInterval(this.heartbeatInterval);
          this.heartbeatInterval = null;
        }

        this.reconnectCount++;
        if (this.reconnectCount <= 5) {
          this.scheduleReconnect();
        }
      });

      // 连接成功事件
      this.socket.on("connect", () => {
        console.log("Socket.IO连接已建立，连接成功！");
        this.isConnected = true;
        this.reconnectCount = 0; // 连接成功后重置重连计数
        this.startHeartbeat();
      });

      // 消息处理 - 监听所有事件
      this.socket.onAny((event, data) => {
        console.log(`收到Socket.IO事件: ${event}`, data);
        this.handleSocketMessage({ event, data });
      });
    } catch (error) {
      console.error("初始化Socket.IO失败:", error);
    }
  }

  // 处理Socket.IO消息
  handleSocketMessage({ event, data }) {
    // 检查不同格式的消息
    if (event) {
      // 用户状态变化通知
      if (event === "user-status-change") {
        this.notifyStatusChange(data);
      }
      // 新消息通知
      else if (event === "new-message") {
        console.log("接收到新消息通知:", data);
        // 触发全局事件，通知所有页面有新消息
        uni.$emit("newMessageReceived", data);
        // 通过回调通知已注册的监听器
        this.notifyNewMessage(data);
      } else if (event === "chat-message") {
        console.log("接收到聊天消息:", data);
        // 触发全局事件，通知所有页面有新消息
        uni.$emit("newMessageReceived", data);
        // 通过回调通知已注册的监听器
        this.notifyNewMessage(data);
      }
      // 认证成功
      else if (event === "auth-success") {
        console.log("Socket.IO认证成功");
        this.isConnected = true;
        this.reconnectCount = 0;
      }
      // 认证错误
      else if (event === "auth-error") {
        console.error("Socket.IO认证错误:", data?.message);
      }
      // 账号在其他设备登录
      else if (event === "login-kick") {
        uni.showToast({
          title: data?.message || "您的账号已在其他设备登录",
          icon: "none",
        });
        uni.removeStorageSync("token");
        uni.removeStorageSync("refreshToken");
        uni.redirectTo({
          url: "/pages/login/login",
        });
      }
      // 心跳响应
      else if (event === "pong-test") {
        console.log("收到心跳响应，延迟:", Date.now() - data?.timestamp, "ms");
      }
    }
  }

  // 发送消息 - 修改为Socket.IO的emit方法
  sendMessage(eventType, data) {
    if (!this.socket || !this.isConnected) {
      console.error("Socket.IO未连接，无法发送消息");
      return Promise.reject(new Error("Socket.IO未连接"));
    }

    return new Promise((resolve, reject) => {
      try {
        this.socket.emit(eventType, data);
        console.log(`消息发送成功: ${eventType}`);
        resolve({ success: true });
      } catch (err) {
        console.error("消息发送失败:", err);
        reject(err);
      }
    });
  }

  // 关闭Socket.IO连接
  close() {
    if (this.reconnectTimeout) {
      clearTimeout(this.reconnectTimeout);
      this.reconnectTimeout = null;
    }

    // 停止心跳
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval);
      this.heartbeatInterval = null;
    }

    if (this.socket) {
      try {
        this.socket.disconnect();
      } catch (e) {
        console.warn("关闭Socket.IO连接失败:", e);
      }
      this.socket = null;
      this.isConnected = false;
      this.reconnectCount = 0;
    }
  }

  // 获取用户在线状态
  async getUserStatus(userId) {
    try {
      const res = await request({
        url: `/user-status/status/${userId}`,
        method: "GET",
      });
      return res;
    } catch (error) {
      console.error(`获取用户${userId}状态失败:`, error);
      return {
        isOnline: false,
        status: "offline",
      };
    }
  }

  // 获取所有在线用户列表
  async getOnlineUsers() {
    try {
      const res = await request({
        url: "/user-status/online-users",
        method: "GET",
      });
      return res;
    } catch (error) {
      console.error("获取在线用户列表失败:", error);
      return {
        onlineUsers: [],
        totalCount: 0,
      };
    }
  }

  // 注册状态变化回调
  onStatusChange(callback) {
    const callbackId = Symbol("statusCallback");
    this.statusCallbacks.set(callbackId, callback);

    // 返回取消注册的函数
    return () => {
      this.statusCallbacks.delete(callbackId);
    };
  }

  // 注册新消息回调
  onNewMessage(callback) {
    const callbackId = Symbol("messageCallback");
    this.messageCallbacks.set(callbackId, callback);

    // 返回取消注册的函数
    return () => {
      this.messageCallbacks.delete(callbackId);
    };
  }

  // 通知状态变化
  notifyStatusChange(data) {
    this.statusCallbacks.forEach((callback) => {
      try {
        callback(data);
      } catch (error) {
        console.error("状态变化回调执行失败:", error);
      }
    });
  }

  // 通知新消息
  notifyNewMessage(data) {
    this.messageCallbacks.forEach((callback) => {
      try {
        callback(data);
      } catch (error) {
        console.error("新消息回调执行失败:", error);
      }
    });

    // 触发全局事件，确保所有页面都能接收到新消息
    uni.$emit("newMessageReceived", data);
  }

  // 调度重连的辅助方法
  scheduleReconnect() {
    if (this.reconnectTimeout) {
      clearTimeout(this.reconnectTimeout);
    }

    // 指数退避策略，避免频繁重连
    const delay = Math.min(1000 * Math.pow(2, this.reconnectCount - 1), 30000);
    console.log(`${delay}ms后尝试第${this.reconnectCount}次重连...`);

    this.reconnectTimeout = setTimeout(() => {
      this.initWebSocket();
    }, delay);
  }

  // 添加心跳机制
  startHeartbeat() {
    // 先清除可能存在的心跳定时器
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval);
      this.heartbeatInterval = null;
    }

    // 每20秒发送一次心跳
    this.heartbeatInterval = setInterval(() => {
      if (this.isConnected && this.socket) {
        try {
          this.socket.emit("ping-test", { timestamp: Date.now() });
        } catch (error) {
          console.warn("发送心跳失败:", error);
        }
      }
    }, 20000);
  }

  // 发送聊天消息
  async sendChatMessage(to, content, messageType = "text") {
    try {
      const result = await this.sendMessage("chat-message", {
        to: to,
        content: content,
        type: messageType,
        timestamp: Date.now(),
      });
      return result;
    } catch (error) {
      console.error("发送聊天消息失败:", error);
      throw error;
    }
  }

  // 发送图片消息
  async sendImageMessage(to, imageUrl, imageInfo = {}) {
    try {
      const result = await this.sendMessage("chat-message", {
        to: to,
        content: {
          url: imageUrl,
          width: imageInfo.width || 0,
          height: imageInfo.height || 0,
          fileSize: imageInfo.fileSize || 0,
          fileName: imageInfo.fileName || "image.jpg",
        },
        type: "image",
        timestamp: Date.now(),
      });
      return result;
    } catch (error) {
      console.error("发送图片消息失败:", error);
      throw error;
    }
  }

  // 发送语音消息
  async sendAudioMessage(to, audioUrl, duration = 0) {
    try {
      const result = await this.sendMessage("chat-message", {
        to: to,
        content: {
          url: audioUrl,
          length: duration,
        },
        type: "audio",
        timestamp: Date.now(),
      });
      return result;
    } catch (error) {
      console.error("发送语音消息失败:", error);
      throw error;
    }
  }
}

// 创建单例实例
const userStatusService = new UserStatusService();

export default userStatusService;
